﻿
Imports System.IO
Imports System.IO.Compression
Imports System.Runtime.CompilerServices

Public Module _compress
    Private Function compress(ByVal i() As Byte,
                              ByRef o() As Byte,
                              ByVal ctor As Func(Of MemoryStream, Stream)) As Boolean
        k_assert(Not ctor Is Nothing)
        If isemptyarray(i) Then
            Return False
        Else
            Using os As MemoryStream = New MemoryStream()
                Using gs As Stream = ctor(os)
                    k_assert(Not gs Is Nothing)
                    gs.Write(i, 0, array_size(i))
                End Using
                o = os.ToArray()
            End Using
            Return True
        End If
    End Function

    <Extension()> Public Function gzip(ByVal i() As Byte, ByRef o() As Byte) As Boolean
        Return compress(i,
                        o,
                        Function(os As MemoryStream) As Stream
                            Return New GZipStream(os, CompressionMode.Compress, True)
                        End Function)
    End Function

    <Extension()> Public Function deflate(ByVal i() As Byte, ByRef o() As Byte) As Boolean
        Return compress(i,
                        o,
                        Function(os As MemoryStream) As Stream
                            Return New DeflateStream(os, CompressionMode.Compress, True)
                        End Function)
    End Function

    <Extension()> Public Function gzip(ByVal i() As Byte) As Byte()
        Dim o() As Byte = Nothing
        k_assert(gzip(i, o))
        Return o
    End Function

    <Extension()> Public Function deflate(ByVal i() As Byte) As Byte()
        Dim o() As Byte = Nothing
        k_assert(deflate(i, o))
        Return o
    End Function

    Private Function decompress(ByVal i() As Byte,
                                ByRef o() As Byte,
                                ByVal ctor As Func(Of MemoryStream, Stream)) As Boolean
        k_assert(Not ctor Is Nothing)
        If isemptyarray(i) Then
            Return False
        Else
            Using os As MemoryStream = New MemoryStream()
                Using gs As Stream = ctor(New MemoryStream(i))
                    k_assert(Not gs Is Nothing)
                    Const buff_size As Int32 = 1024
                    Dim buff() As Byte = Nothing
                    ReDim buff(buff_size - 1)
                    Dim rc As Int32 = 0
                    While True
                        rc = gs.Read(buff, 0, buff_size)
                        If rc = 0 Then
                            Exit While
                        Else
                            os.Write(buff, 0, rc)
                        End If
                    End While
                End Using
                o = os.ToArray()
            End Using
            Return True
        End If
    End Function

    <Extension()> Public Function ungzip(ByVal i() As Byte, ByRef o() As Byte) As Boolean
        Return decompress(i,
                          o,
                          Function(s As MemoryStream) As Stream
                              Return New GZipStream(s, CompressionMode.Decompress, False)
                          End Function)
    End Function

    <Extension()> Public Function undeflate(ByVal i() As Byte, ByRef o() As Byte) As Boolean
        Return decompress(i,
                          o,
                          Function(s As MemoryStream) As Stream
                              Return New DeflateStream(s, CompressionMode.Decompress, False)
                          End Function)
    End Function

    <Extension()> Public Function ungzip(ByVal i() As Byte) As Byte()
        Dim o() As Byte = Nothing
        k_assert(ungzip(i, o))
        Return o
    End Function

    <Extension()> Public Function undeflate(ByVal i() As Byte) As Byte()
        Dim o() As Byte = Nothing
        k_assert(undeflate(i, o))
        Return o
    End Function
End Module
